package com.king.freefish.common.util;

import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * @packageName com.king.freefish.common.util
 * @author: jinguoguang
 * @date: 2025/7/30 08:46
 * @description:
 **/
public class IpUtil {
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST = "127.0.0.1";
    private static final String ANYHOST = "0.0.0.0";
    private static final Pattern IPV4_PATTERN = Pattern.compile(
            "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])$");

    private static final String[] HEADERS_TO_TRY = {
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_X_FORWARDED_FOR",
            "HTTP_X_FORWARDED",
            "HTTP_X_CLUSTER_CLIENT_IP",
            "HTTP_CLIENT_IP",
            "HTTP_FORWARDED_FOR",
            "HTTP_FORWARDED",
            "HTTP_VIA",
            "REMOTE_ADDR"
    };

    /**
     * 获取客户端真实IP地址（处理代理服务器情况）
     *
     * @param request HttpServletRequest对象
     * @return 客户端真实IP地址
     */
    public static String getClientIpAddress(HttpServletRequest request) {
        for (String header : HEADERS_TO_TRY) {
            String ip = request.getHeader(header);
            if (ip != null && !ip.isEmpty() && !UNKNOWN.equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个IP值，第一个为真实IP
                int index = ip.indexOf(',');
                if (index != -1) {
                    return ip.substring(0, index).trim();
                } else {
                    return ip.trim();
                }
            }
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取服务器的第一个非回环IPv4地址
     *
     * @return 服务器IP地址，如果未找到则返回null
     */
    public static String getServerIpAddress() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                // 跳过回环接口、未激活接口和虚拟接口
                if (ni.isLoopback() || !ni.isUp() || ni.isVirtual()) {
                    continue;
                }

                Enumeration<InetAddress> addresses = ni.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    // 只返回IPv4地址
                    if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
                        String ip = addr.getHostAddress();
                        if (isIPv4Valid(ip)) {
                            return ip;
                        }
                    }
                }
            }
            // 如果没有找到非回环地址，尝试获取本地主机地址
            return InetAddress.getLocalHost().getHostAddress();
        } catch (SocketException | UnknownHostException e) {
            // 记录异常或使用默认值
            return LOCALHOST;
        }
    }

    /**
     * 检查IP地址是否为有效的IPv4地址
     *
     * @param ip IP地址
     * @return 是否为有效IPv4地址
     */
    public static boolean isIPv4Valid(String ip) {
        return IPV4_PATTERN.matcher(ip).matches();
    }

    /**
     * 检查IP地址是否在指定的IP段内
     *
     * @param ip        待检查的IP地址
     * @param ipSegment IP段，格式如"192.168.1.0/24"
     * @return 是否在IP段内
     */
    public static boolean isIpInRange(String ip, String ipSegment) {
        try {
            String[] segmentParts = ipSegment.split("/");
            if (segmentParts.length != 2) {
                return false;
            }

            String baseIp = segmentParts[0];
            int prefixLength = Integer.parseInt(segmentParts[1]);

            InetAddress address = InetAddress.getByName(ip);
            InetAddress baseAddress = InetAddress.getByName(baseIp);

            if (address instanceof Inet4Address && baseAddress instanceof Inet4Address) {
                int mask = 0xFFFFFFFF << (32 - prefixLength);
                int ipInt = ipToInt((Inet4Address) address);
                int baseIpInt = ipToInt((Inet4Address) baseAddress);

                return (ipInt & mask) == (baseIpInt & mask);
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将IPv4地址转换为整数
     *
     * @param address IPv4地址
     * @return 整数值
     */
    private static int ipToInt(Inet4Address address) {
        byte[] bytes = address.getAddress();
        int result = 0;
        for (byte b : bytes) {
            result = (result << 8) | (b & 0xFF);
        }
        return result;
    }


    // public void testDemo() {
    //     // 在Servlet中获取客户端IP
    //     // String clientIp = getClientIpAddress(request);
    //
    //     // 获取服务器IP
    //     String serverIp = getServerIpAddress();
    //
    //    // 检查IP是否有效
    //     boolean isValid = isIPv4Valid("192.168.1.1");
    //
    //    // 检查IP是否在网段内
    //     boolean inRange = isIpInRange("192.168.1.5", "192.168.1.0/24");
    // }
}
